package com.zero.guava.samples.CollectionsDemo;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.*;
import java.util.concurrent.ConcurrentMap;

public class MapsDemo {

    enum Operate{
        ADD, UPDATE, DELETE;
    }

    public static void main(String[] args) {

        Map<String, String> hashMap = Maps.newHashMap();
        LinkedHashMap<Object, Object> linkedHashMap = Maps.newLinkedHashMap();
        ConcurrentMap<Object, Object> concurrentMap = Maps.newConcurrentMap();
        TreeMap<Comparable, Object> treeMap = Maps.newTreeMap();
        EnumMap<Operate, String> enumMap = Maps.newEnumMap(Operate.class);
        enumMap.put(Operate.ADD, "add operate");
        enumMap.put(Operate.UPDATE, "UPDATE operate");
        enumMap.put(Operate.DELETE, "DELETE operate");
        System.out.println(enumMap);

        testMaps();
    }


    public static void testMaps() {

        /**
         * difference：返回两个给定map之间的差异。
         */
        Map<String, String> map1 = new HashMap<>();
        Map<String, String> map2 = new HashMap<>();
        Map<String, String> map3 = new HashMap<>();
        map1.put("a","1");
        map2.put("b","2");
        map3.put("c","3");
        System.out.println(Maps.difference(map1, map2));

        /**
         * asMap：返回一个活动的map
         * 键值为给定的set中的值
         * value为通过给定Function计算后的值。
         */

        Set<String> set = Sets.newHashSet("a", "b", "c");

        Function<String, String> function = new Function<String, String>() {
            @Override
            public String apply(String input) {
                return input.toUpperCase();
            }
        };
        Map<String, String> asMap = Maps.asMap(set, function);
        System.out.println(asMap);

        /**
         * toMap：返回一个不可变的ImmutableMap实例
         * 其键值为给定keys中去除重复值后的值
         * 其值为键被计算了valueFunction后的值
         */

        List<String> lists = Lists.newArrayList("a", "b", "c","a");
        System.out.println(Maps.toMap(lists,function));

        /**
         * uniqueIndex：返回一个不可变的ImmutableMap实例，
         * 其value值为按照给定顺序的给定的values值
         * 键值为相应的值经过给定Function计算后的值
         */
        List<String> values = Lists.newArrayList("a", "b", "c", "d");
        System.out.println(Maps.uniqueIndex(values,function));

        /**
         * transformValues：返回一个map映射
         * 其键值为给定fromMap的键值
         * 其value为给定formMap中value通过Function转换后的值
         */
        Map<String, Boolean> fromMap = Maps.newHashMap();
        fromMap.put("key", true);
        fromMap.put("value", false);
        //输出：{value=true, key=false}
        System.out.println(Maps.transformValues(fromMap, new Function<Boolean, Object>() {
            @Override
            public Object apply(Boolean input) {
                //对传入的元素取反
                return !input;
            }
        }));

        /**
         * transformEntries：返回一个map映射
         * 其Entry为给定fromMap.Entry通过给定EntryTransformer转换后的值
         */
        Maps.EntryTransformer<String, Boolean, String> entryTransformer = new Maps.EntryTransformer<String, Boolean, String>() {
            @Override
            public String transformEntry(String key, Boolean value) {
                return  value ? key : key.toUpperCase();
            }
        };
        System.out.println(Maps.transformEntries(fromMap,entryTransformer));

        /**
         * filterKeys：返回给定unfilteredMap中的键值通过给定keyPredicate过滤后的map映射
         */

        Map<String, Boolean> filterKey = Maps.filterKeys(fromMap, new Predicate<String>() {
            @Override
            public boolean apply(String input) {
                return input.contains("y");
            }
        });
        System.out.println(filterKey);

        /**
         * filterValues：返回给定unfilteredMap中的value值通过给定keyPredicate过滤后的map映射
         */
        //输出：{value=false}
        System.out.println(Maps.filterValues(fromMap, new Predicate<Boolean>() {
            @Override
            public boolean apply(Boolean input) {
                //过滤Map中value值为假的元素
                return !input;
            }
        }));

        /**
         * filterEntries：返回给定unfilteredMap.Entry中的Entry值通过给定entryPredicate过滤后的map映射
         */
        System.out.println(Maps.filterEntries(fromMap, new Predicate<Map.Entry<String, Boolean>>() {
            @Override
            public boolean apply(Map.Entry<String, Boolean> input) {
                //过滤Map.Entry中getValue()为真的元素
                return input.getValue();
            }
        }));
    }

}
